package com.yjw.demo.pattern.delegate;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.yjw.demo.pattern.delegate.action.UserAction;

/**
 * 委派模式
 * 
 * @author yinjianwei
 * @date 2018/12/23
 */
public class DispatchServlet {

    private static List<Handler> handlers = new ArrayList<>();

    static {
        try {
            Class<UserAction> userActionClass = UserAction.class;
            handlers.add(new Handler(userActionClass.newInstance(), userActionClass.getMethod("getUsers", null),
                "/api/getUsers"));
        } catch (InstantiationException | IllegalAccessException | NoSuchMethodException | SecurityException e) {
            e.printStackTrace();
        }
    }

    public void doService(HttpServletRequest request, HttpServletResponse response) {
        doDispatch(request, response);
    }

    private void doDispatch(HttpServletRequest request, HttpServletResponse response) {
        // 1.获取用户请求的URL
        String uri = request.getRequestURI();

        // 2.根据用户请求的URL获取Handler
        Handler handler = null;
        for (Handler h : handlers) {
            if (uri.equals(h.getUrl())) {
                handler = h;
                break;
            }
        }
        // 3.执行Handler指向的方法
        Object obj = null;
        try {
            obj = handler.getMethod().invoke(handler.getAction(), null);
        } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
            e.printStackTrace();
        }
        // 4.获取执行结果，通过respond返回
        // response.getWriter().write();
    }

}

class Handler {

    private Object action;
    private Method method;
    private String url;

    public Handler(Object action, Method method, String url) {
        this.action = action;
        this.method = method;
        this.url = url;
    }

    public Object getAction() {
        return action;
    }

    public void setAction(Object action) {
        this.action = action;
    }

    public Method getMethod() {
        return method;
    }

    public void setMethod(Method method) {
        this.method = method;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

}